#include "test.h"
#include "type.h"
#include "base64.h"
#include <iconv.h>
#include <stdlib.h>
#include <string.h>

#define VERBOSE
#define HTTP_FLAGS "POST /music.yl"

#define HTTP_BUF_SIZE 4000

#define WRITE_MAX_NUM 3
int wirtenum = 0;

#define MAX_MSG_LENGTH 8192

static int convert(const char *from, const char *to, char* save, int savelen, char *src, int srclen)
{
    iconv_t cd;
    char   *inbuf = src;
    char *outbuf = save;
    size_t outbufsize = savelen;
    int status = 0;
    size_t  savesize = 0;
    size_t inbufsize = srclen;
    const char* inptr = inbuf;
    size_t      insize = inbufsize;
    char* outptr = outbuf;
    size_t outsize = outbufsize;

    cd = iconv_open(to, from);
    iconv(cd,NULL,NULL,NULL,NULL);
    if (inbufsize == 0) {
        status = -1;
        goto done;
    }
    while (insize > 0) {
        size_t res = iconv(cd, (char**)&inptr, &insize,(char**)&outptr, &outsize);
        if (outptr != outbuf) {
            int saved_errno = errno;
            int outsize = outptr - outbuf;
            strncpy(save+savesize, outbuf, outsize);
            errno = saved_errno;
        }
        if (res == (size_t)(-1)) {
            if (errno == EILSEQ) {
                int one = 1;
                iconvctl(cd,ICONV_SET_DISCARD_ILSEQ,&one);
                status = -3;
            } else if (errno == EINVAL) {
                if (inbufsize == 0) {
                    status = -4;
                    goto done;
                } else {
                    break;
                }
            } else if (errno == E2BIG) {
                status = -5;
                goto done;
            } else {
                status = -6;
                goto done;
            }
        }
    }
    status = strlen(save);
done:
    iconv_close(cd);
    return status;

}

void test(struct pcap_pkthdr *header, const u_int8_t *data)
{
    struct tm *newtime;
    char tmpbuf[80];
    newtime=localtime(&(header->ts.tv_sec));
    strftime(tmpbuf, 80,"%H:%M:%S",newtime);
    //printf("%s:%ld ",tmpbuf, header->ts.tv_usec);

    Pether_header s ;
    s = (Pether_header)(data);
    switch(htons(s->ether_type)) {
        case EPT_IP: {
            // printf("IP ");
            analysisIP(data);
            break;
        }
#if 0
        case EPT_ARP: {
            printf("ARP,");
            analysisARP(data);
            break;
        }
        case EPT_RARP: {
            printf("RARP ");
            break;
        }
#endif
        default:
            //printf("proto: %.4x \n",ntohs(s->ether_type));
            return;

    }
    //printf(", length %u\n", header->caplen);
}

void analysisIP(const u_int8_t *data)
{
    Pip_header s = (Pip_header)(data+14);
    //printf(" %d.%d.%d.%d > %d.%d.%d.%d ",s->ip_source_address[0],s->ip_source_address[1],s->ip_source_address[2],s->ip_source_address[3], s->ip_destination_address[0], s->ip_destination_address[1], s->ip_destination_address[2], s->ip_destination_address[3]);

    char httpbuf[HTTP_BUF_SIZE] = {0};
    int httplen = 0;
    char *httppayload = NULL;
    static int flag = 0;
    switch(s->ip_protocol) {
        case 0x06: {
            Ptcp_header tmp = (Ptcp_header)(data+14+20);
            httppayload = (char *)(data + 14 + 20 + 20);
            httplen = ntohs(s->ip_length) - s->ip_header_length*4 - 20;

            if(httplen > 0 && 80 == htons(tmp->tcp_destination_port) ) {
                if(memcmp(httppayload, HTTP_FLAGS, strlen(HTTP_FLAGS)) == 0 || flag == 1) {
                    flag++;
                    memcpy(httpbuf, httppayload, httplen);
                    *(httpbuf+httplen) = '\0';
#if 1

                    printf("\n-----flag: %d-----%d---------\n%s\n-------------------\n", flag, httplen, httpbuf);

#endif

                    if(flag == 2) {
                        printf("capture num: %d\n",wirtenum + 1);
                        char tmppost[MAX_MSG_LENGTH]= {0};
                        base64_decode((unsigned char*)httpbuf, (unsigned)httplen, (unsigned char*)&tmppost);
#if 0
                        if(strstr(tmppost,"ACT:PLAY_MUSIC") == NULL) {
#endif
                            char tmpout[MAX_MSG_LENGTH]= {0};
                            convert("UTF-8", "GB2312",tmpout, MAX_MSG_LENGTH, tmppost, strlen(tmppost));

                            printf("info: [%s]\n", tmppost);
#if 0
                        }
#endif


                        FILE *fb = fopen("info.txt", "ab+");
                        if(fb) {
                            wirtenum++;
                            fprintf(fb, " %s\n", httpbuf);
                            fclose(fb);
                        }

                        if(wirtenum >= WRITE_MAX_NUM) {
                            printf("capture num great than max, now exit \n");
                            exit(0);
                        }
                    }
                } else
                    flag = 0;
            } else {
                flag = 0;
            }
            break;

        }
#if 0
        case 0x11: {
            printf("UDP");
            Pudp_header tmp = (Pudp_header)(data+14+20);
            printf(" %d > %d ",htons(tmp->udp_source_port), htons(tmp->udp_destination_port));

            break;
        }
        case 0x01: {

            printf("ICMP");
            Picmp_header s = (Picmp_header)(data+14+20);
            char tmp[10];
            if(0x0 == s->icmp_type && 0x0 == s->icmp_code)
                sprintf(tmp,"%s","reply");
            else if(0x8 == s->icmp_type && 0x0 == s->icmp_code)
                sprintf(tmp,"%s","request");
            else
                sprintf(tmp,"%x %x",s->icmp_type, s->icmp_code);
            printf(" echo %s, id %d, seq %d", tmp,s->icmp_id, s->icmp_sequence);
            break;
        }
#endif
        default:
            flag = 0;
            //printf("%d\n",s->ip_protocol);
            return;
    }
}
void analysisTCP(struct pcap_pkthdr *header, const u_int8_t *data)
{
}

void analysisARP(const u_int8_t *data)
{
    Parp_header s = (Parp_header) (data+14);
    if(ARP_REQUEST == htons(s->arp_operation_code)) {
        printf(" Request");
        printf(" Who has %d.%d.%d.%d tell %d.%d.%d.%d ",s->arp_destination_ip_address[0],s->arp_destination_ip_address[1],s->arp_destination_ip_address[2],s->arp_destination_ip_address[3], s->arp_source_ip_address[0], s->arp_source_ip_address[1], s->arp_source_ip_address[2], s->arp_source_ip_address[3]);
    } else if(ARP_REPLAY == htons(s->arp_operation_code)) {
        printf(" Reply");
        printf(" %d.%d.%d.%d is-at ",s->arp_destination_ip_address[0],s->arp_destination_ip_address[1],s->arp_destination_ip_address[2],s->arp_destination_ip_address[3]);
        printMACaddress(s->arp_source_ethernet_address);
    } else
        printf(" %04x",htons(s->arp_operation_code));
}
